package com.zhaokuner.parentstarter.utils;

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;

/**
 * 类描述:时间
 *
 * @author 赵希坤 zhaoxikun
 * @date 2020/12/28 20:59
 */
public class MyDateUtils {
    /**
     * 一天的毫秒
     */
    public static final long DAY1 = 1000L * 60 * 60 * 24;
    /**
     * 七天的毫秒
     */
    public static final long DAY7 = 7 * DAY1;

    /**
     * yyyyMM
     */
    public static final DateTimeFormatter YYYYMM_FORMATTER = DateTimeFormatter.ofPattern("yyyyMM");

    /**
     * yyyyMMdd
     */
    public static final DateTimeFormatter YYYYMMDD_FORMATTER = DateTimeFormatter.ofPattern("yyyyMMdd");
    /**
     * yyyy-MM-dd HH:mm:ss
     */
    public static final DateTimeFormatter YYYY_MM_DD_HH_MM_SS_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    /**
     * yyyyMMddHHmmss
     */
    public static final DateTimeFormatter YYYYMMDDHHMMSS_FORMATTER = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
    /**
     * "一", "二", "三", "四", "五", "六", "日"
     */
    private static String[] WEEK_NAME_ARRAY = new String[]{"一", "二", "三", "四", "五", "六", "日"};

    /**
     * "一", "二", "三", "四", "五", "六", "日"
     *
     * @param millisecond millisecond
     * @return string
     */
    public static String getWeekName(Long millisecond) {
        LocalDateTime time = getLocalDateTime(millisecond);
        DayOfWeek week = time.getDayOfWeek();
        return WEEK_NAME_ARRAY[week.getValue() - 1];
    }

    /**
     * 获取毫秒 北京时间 东八区
     *
     * @param localDateTime 毫秒
     * @return millisecond
     */
    public static Long getMillisecond(LocalDateTime localDateTime) {
        return localDateTime.toInstant(ZoneOffset.of("+8")).toEpochMilli();
    }

    /**
     * 根据毫秒获取
     *
     * @param millisecond 毫秒
     * @return LocalDateTime
     */
    public static LocalDateTime getLocalDateTime(Long millisecond) {
        Instant instant = Instant.ofEpochMilli(millisecond);
        return LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
    }

    /**
     * yyyyMMdd
     *
     * @param millisecond 毫秒
     * @return 格式化
     */
    public static String formatYyyyMMdd(Long millisecond) {
        return getLocalDateTime(millisecond).format(YYYYMMDD_FORMATTER);
    }

    /**
     * yyyy-MM-dd HH:mm:ss
     *
     * @param millisecond 毫秒
     * @return 格式化
     */
    public static String formatYyyyMMddHHmmss(Long millisecond) {
        return getLocalDateTime(millisecond).format(YYYY_MM_DD_HH_MM_SS_FORMATTER);
    }

    /**
     * 几岁几个月几天几小时几分几秒
     */
    public static class Age {
        /**
         * 几岁
         */
        public int year = 0;
        /**
         * 几个月
         */
        public int month = 0;
        /**
         * 几天
         */
        public int day = 0;
        /**
         * 几小时
         */
        public int hour = 0;
        /**
         * 几分
         */
        public int minute = 0;
        /**
         * 几秒
         */
        public int second = 0;

        @Override
        public String toString() {
            return new StringBuffer("{").append("year:").append(year).append(",").append("month:").append(month)
                    .append(",").append("day:").append(day).append(",").append("hour:").append(hour).append(",")
                    .append("minute:").append(minute).append(",").append("second:").append(second).append("}").toString();
        }

    }

    /**
     * @return 几岁几个月
     */
    public static String ageYearMonth(Age age) {
        StringBuilder sage = new StringBuilder();
        if (age.year > 0) {
            sage.append(age.year).append("岁");
        }
        if (age.month > 0) {
            sage.append(age.month).append("个月");
        }
        if (age.year == 0 && age.month == 0) {
            if (age.day > 0 || age.hour > 0 || age.minute > 0 || age.second > 0) {
                sage.append(1).append("个月");
            } else {
                sage.append(0).append("岁");
            }
        }
        return sage.toString();
    }

    /**
     * @return **前
     */
    public static String ageDifference(Age age) {
        StringBuffer sb = new StringBuffer();
        if (age.year != 0) {
            return sb.append(age.year).append("年前").toString();
        } else if (age.month != 0) {
            return sb.append(age.month).append("月前").toString();
        } else if (age.day != 0) {
            return sb.append(age.day).append("天前").toString();
        } else if (age.hour != 0) {
            return sb.append(age.hour).append("小时前").toString();
        } else if (age.minute != 0) {
            return sb.append(age.minute).append("分钟前").toString();
        } else {
            return sb.append("刚刚").toString();
        }
    }

    /**
     * <p>
     * Title: getAge
     * <p>
     * Description: 年龄的秒
     *
     * @param beginTime 开始时间
     * @param endTime   结束时间
     * @return
     * @author zhaokuner
     */
    public static Age getAge(Integer beginTime, Integer endTime) {
        Age age = new Age();
        if (null != beginTime && null != endTime) {
            Calendar bc = Calendar.getInstance();
            bc.setTimeInMillis(beginTime * 1000L);
            Calendar ec = Calendar.getInstance();
            ec.setTimeInMillis(endTime * 1000L);
            age.second = ec.get(Calendar.SECOND) - bc.get(Calendar.SECOND);
            if (age.second < 0) {
                ec.add(Calendar.MINUTE, -1);
                age.second = age.second + 60;
            }
            age.minute = ec.get(Calendar.MINUTE) - bc.get(Calendar.MINUTE);
            if (age.minute < 0) {
                ec.add(Calendar.HOUR_OF_DAY, -1);
                age.minute = age.minute + 60;
            }
            age.hour = ec.get(Calendar.HOUR_OF_DAY) - bc.get(Calendar.HOUR_OF_DAY);
            if (age.hour < 0) {
                ec.add(Calendar.DAY_OF_MONTH, -1);
                age.hour = age.hour + 24;
            }
            age.day = ec.get(Calendar.DAY_OF_MONTH) - bc.get(Calendar.DAY_OF_MONTH);
            if (age.day < 0) {
                ec.add(Calendar.MONTH, -1);
                // 计算上月的天数
                Month m = getMonth(new Date(ec.getTimeInMillis()));
                age.day = age.day + (int) ((m.lastDay24 - m.firstDay0 + 1) / (24 * 60 * 60 * 1000));
            }
            age.month = ec.get(Calendar.MONTH) - bc.get(Calendar.MONTH);
            if (age.month < 0) {
                ec.add(Calendar.YEAR, -1);
                age.month = age.month + 12;
            }
            age.year = ec.get(Calendar.YEAR) - bc.get(Calendar.YEAR);
            if (age.year < 0) {
                // 说明输入参数有误
                return new Age();
            }
        }
        return age;
    }

    /**
     * 一天的0点和24点
     */
    public static class Day {
        /**
         * 毫秒 0点
         */
        public Long clock0 = 0L;
        /**
         * 毫秒 24点
         */
        public Long clock24 = 24L;
        /**
         * 秒 0点
         */
        public Integer clock0Second = 0;
        /**
         * 秒 24点
         */
        public Integer clock24Second = 24;
    }

    /**
     * 获取某一天的0点和24点
     */
    public static Day getDay(Long millis) {
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(millis);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        Day today = new Day();
        today.clock0 = cal.getTimeInMillis();
        today.clock0Second = (int) (today.clock0 / 1000);
        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.SECOND, 59);
        cal.set(Calendar.MILLISECOND, 999);
        today.clock24 = cal.getTimeInMillis();
        today.clock24Second = (int) (today.clock24 / 1000);
        return today;
    }

    /**
     * 获取某一天的0点和24点
     */
    public static Day getDay(Date now) {
        return getDay(now.getTime());
    }

    /**
     * 中国 周一~周日
     */
    public static class Week {
        public Long firstDayMonday0 = 0L;
        public Long lastDaySunday24 = 0L;
        public Integer firstDayMonday0Second = 0;
        public Integer lastDaySunday24Second = 0;
    }


    /**
     * 中国 周一~周日
     */
    public static Week getWeek(Long millisecond) {
        return getWeek(new Date(millisecond));
    }

    /**
     * 中国 周一~周日
     */
    public static Week getWeek(Date now) {
        Week w = new Week();
        /** 以下先根据第一个时间找出所在周的星期一、星期日, 再对第二个时间进行比较 */
        Calendar cal = Calendar.getInstance();
        cal.setTime(now);
        // 判断要计算的日期是否是周日，如果是则减一天计算周六的，否则会出问题，计算到下一周去了
        // 获得当前日期是一个星期的第几天
        int dayWeek = cal.get(Calendar.DAY_OF_WEEK);
        if (1 == dayWeek) {
            cal.add(Calendar.DAY_OF_MONTH, -1);
        }
        // 设置一个星期的第一天，按中国的习惯一个星期的第一天是星期一
        cal.setFirstDayOfWeek(Calendar.MONDAY);
        // 获得当前日期是一个星期的第几天
        int day = cal.get(Calendar.DAY_OF_WEEK);
        // 根据日历的规则，给当前日期减去星期几与一个星期第一天的差值
        cal.add(Calendar.DATE, cal.getFirstDayOfWeek() - day);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        w.firstDayMonday0 = cal.getTimeInMillis();
        w.firstDayMonday0Second = (int) (w.firstDayMonday0 / 1000);
        cal.add(Calendar.DATE, 6);
        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.SECOND, 59);
        cal.set(Calendar.MILLISECOND, 999);
        w.lastDaySunday24 = cal.getTimeInMillis();
        w.lastDaySunday24Second = (int) (w.lastDaySunday24 / 1000);

        return w;
    }

    public static class Month {
        public Long firstDay0 = 0L;
        public Long lastDay24 = 0L;
        public Integer firstDay0Second = 0;
        public Integer lastDay24Second = 0;
    }

    public static Month getMonth(Date now) {
        Month m = new Month();

        Calendar cal = Calendar.getInstance();
        cal.setTime(now);
        cal.set(Calendar.DAY_OF_MONTH, 1);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        m.firstDay0 = cal.getTimeInMillis();
        m.firstDay0Second = (int) (m.firstDay0 / 1000);

        cal.add(Calendar.MONTH, 1);
        cal.add(Calendar.DAY_OF_MONTH, -1);
        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.SECOND, 59);
        cal.set(Calendar.MILLISECOND, 999);
        m.lastDay24 = cal.getTimeInMillis();
        m.lastDay24Second = (int) (m.lastDay24 / 1000);

        return m;
    }

    public static class Year {
        public Long firstDay0 = 0L;
        public Long lastDay24 = 0L;
        public Integer firstDay0Second = 0;
        public Integer lastDay24Second = 0;
    }

    public static Year getYear(Date now) {
        Year y = new Year();
        Calendar cal = Calendar.getInstance();
        cal.setTime(now);
        cal.set(Calendar.DAY_OF_YEAR, 1);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        y.firstDay0 = cal.getTimeInMillis();
        y.firstDay0Second = (int) (y.firstDay0 / 1000);

        cal.add(Calendar.YEAR, 1);
        cal.add(Calendar.DAY_OF_YEAR, -1);
        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.SECOND, 59);
        cal.set(Calendar.MILLISECOND, 999);
        y.lastDay24 = cal.getTimeInMillis();
        y.lastDay24Second = (int) (y.lastDay24 / 1000);

        return y;
    }

}
